package com.example.pm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.pm.common.redis.RedisUtils;
import com.example.pm.common.result.R;
import com.example.pm.common.utils.*;
import com.example.pm.domain.Bo.PageBo;
import com.example.pm.domain.Employee;
import com.example.pm.domain.Image;
import com.example.pm.domain.Notice;
import com.example.pm.domain.Vo.PageVo;
import com.example.pm.mapper.EmployeeMapper;
import com.example.pm.mapper.ImageMapper;
import com.example.pm.mapper.NoticeMapper;
import com.example.pm.service.EmployeeService;
import com.example.pm.service.UserService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    private ImageMapper imageMapper;
    @Autowired
    private GzipUtils gzipUtils;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private NoticeMapper noticeMapper;
    @Autowired
    private UserService userService;

    @Override
    public R<PageVo<Object>> getEmployees(PageBo pageBo, String jzzt) {
        List<Employee> list = employeeMapper.getEmployees();
        list = list.stream().filter(o -> jzzt.equals(o.getJzzt())).collect(Collectors.toList());
        list = list.stream().peek(this::SetEmpty).collect(Collectors.toList());
        //离职人员按离职时间排序
        if (jzzt.equals("离职")) {
            list = list.stream().sorted(Comparator.comparing(Employee::getLzrq, Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
        }
        PageVo<Object> vo = new PageVo<>(pageBo, list);
        if (list.isEmpty()) {
            return R.info("没有符合条件的数据", vo);
        }
        return R.ok(vo);
    }

    @Override
    public R<PageVo<Object>> getEmployeeBySearch(Employee employee, PageBo pageBo, String jzzt) {
        LambdaQueryWrapper<Employee> lqw = new LambdaQueryWrapper<>();
        lqw.like(Employee::getJzzt, jzzt);
        if (employee.getDah() != null) {
            lqw.like(Employee::getDah, employee.getDah());
        }
        if (employee.getXm() != null && !employee.getXm().isEmpty()) {
            lqw.like(Employee::getXm, employee.getXm());
        }
        if (employee.getBm() != null && !employee.getBm().isEmpty()) {
            lqw.like(Employee::getBm, employee.getBm());
        }
        if (employee.getXb() != null && !employee.getXb().isEmpty()) {
            lqw.like(Employee::getXb, employee.getXb());
        }
        if (employee.getJzzt() != null && !employee.getJzzt().isEmpty()) {
            lqw.like(Employee::getJzzt, employee.getJzzt());
        }
        if (employee.getZw() != null && !employee.getZw().isEmpty()) {
            lqw.like(Employee::getZw, employee.getZw());
        }
        if (employee.getMz() != null && !employee.getMz().isEmpty()) {
            lqw.like(Employee::getMz, employee.getMz());
        }
        if (employee.getSfz() != null && !employee.getSfz().isEmpty()) {
            lqw.like(Employee::getSfz, employee.getSfz());
        }
        List<Employee> list = employeeMapper.selectList(lqw);
        list = list.stream().peek(this::SetEmpty).collect(Collectors.toList());
        //离职人员按离职时间排序
        if (jzzt.equals("离职")) {
            list = list.stream().sorted(Comparator.comparing(Employee::getLzrq, Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
        }
        PageVo<Object> vo = new PageVo<>(pageBo, list);
        if (list.isEmpty()) {
            return R.info("没有符合条件的数据", vo);
        }
        return R.ok(vo);
    }

    /**
     * 部门 bm
     * 性别 xb
     * 就职状态 jzzt
     * 民族 mz
     */
    @Override
    public R<Object> EmployeeSearchOption() {
        List<Employee> list = employeeMapper.getEmployees();
        List<String> bm = list.stream().map(Employee::getBm).filter(o -> o != null && !o.isEmpty() && !o.replace(" ", "").isEmpty()).distinct().collect(Collectors.toList());
        List<String> xb = list.stream().map(Employee::getXb).filter(o -> o != null && !o.isEmpty() && !o.replace(" ", "").isEmpty()).distinct().collect(Collectors.toList());
//        List<String> jzzt = list.stream().map(Employee::getJzzt).filter(o -> o != null && !o.isEmpty() && !o.replace(" ", "").isEmpty()).distinct().collect(Collectors.toList());
        List<String> mz = getMz();
        Map<String, Object> map = new HashMap<>();
        map.put("bm", bm);
        map.put("xb", xb);
//        map.put("jzzt", jzzt);
        map.put("mz", mz);
        return R.ok(map);
    }

    @Override
    public R<Object> insertEmployee(Employee employee, PageBo pageBo) {
        String sfz = employee.getSfz();
        //身份证计算出生日期
        employee.setCsrq(setCsrq(sfz));
        //计算年龄
        employee.setNl(setNl(employee.getCsrq()));
        //计算性别
        employee.setXb(setXb(sfz));
        //设置入职日期
        employee.setRzrq(LocalDateTime.now());
        //设置入场年限
        employee.setRcnx(setRcnx(employee.getRzrq(), null));
        //设置籍贯
        employee.setJg(setJg(sfz));
        employee.setHkszd(employee.getJg());
        //设置就职状态
        employee.setJzzt("在职");
        //设置头像
        employee.setTxid(1);
        //设置合同状态
        employee.setHt("未签");
        //设置保密协议
        employee.setBmxy("未签");
        //设置档案号
        employee.setDah(employeeMapper.getLastDah() + 1);
        employeeMapper.insertEmployee(employee);
        userService.createUserRedis();
        return R.ok("添加成功", getEmployees(pageBo, "在职"));
    }

    @Override
    public R<Object> deleteEmployee(String id, PageBo pageBo) {
        LambdaQueryWrapper<Employee> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Employee::getId, id);
        employeeMapper.delete(lqw);
        return R.ok("删除成功", getEmployees(pageBo, ""));
    }

    @Override
    public R<PageVo<Object>> updateEmployee(Employee employee, PageBo pageBo) {
        if ("未签".equals(employee.getHt())) {
            employee.setHtks(null);
            employee.setHtjs(null);
        }
        if ("离职".equals(employee.getJzzt()) || "退休".equals(employee.getJzzt())) {
            employee.setLzrq(LocalDateTime.now());
        }
        employeeMapper.updateById(employee);
        return R.ok("更新成功", getEmployees(pageBo, "").getData());
    }

    /**
     * 获取员工信息登记表图片
     *
     * @param id 员工id
     */
    @Override
    public R<Object> getXxdjb(Integer id) {
        String image = imageMapper.getXxdjb(id);
        if (image == null)
            return R.info("该用户未上传电子版信息登记表", null);
        Map<String, Object> map = new HashMap<>();
        map.put("image", gzipUtils.compress(image));
        return R.ok(map);
    }

    @SneakyThrows
    @Override
    public R<Object> insertXxdjb(Image image) {
        String encoder = "data:image/jpg;base64,";
        String base64 = encoder + ImageUtils.convertImageToBase64Str((String) redisUtils.get(image.getImage()));
        image.setImage(base64);
        imageMapper.insertXxdjb(image);
        return R.ok("上传成功");
    }

    @Override
    public R<Object> getXsxwzs(Integer id) {
        String image = imageMapper.getXsxwzs(id);
        if (image == null)
            return R.info("该用户未上传电子版学士学位证书", null);
        Map<String, Object> map = new HashMap<>();
        map.put("image", gzipUtils.compress(image));
        return R.ok(map);
    }

    @Override
    public R<Object> insertXsxwzs(Image image) {
        String encoder = "data:image/jpg;base64,";
        String base64 = encoder + ImageUtils.convertImageToBase64Str((String) redisUtils.get(image.getImage()));
        image.setImage(base64);
        imageMapper.insertXsxwzs(image);
        return R.ok("上传成功");
    }

    @Override
    public R<Object> getByzs(Integer id) {
        String image = imageMapper.getByzs(id);
        if (image == null)
            return R.info("该用户未上传电子版学士学位证书", null);
        Map<String, Object> map = new HashMap<>();
        map.put("image", gzipUtils.compress(image));
        return R.ok(map);
    }

    @Override
    public R<Object> insertByzs(Image image) {
        String encoder = "data:image/jpg;base64,";
        String base64 = encoder + ImageUtils.convertImageToBase64Str((String) redisUtils.get(image.getImage()));
        image.setImage(base64);
        imageMapper.insertByzs(image);
        return R.ok("上传成功");
    }

    @Override
    public R<Object> getZczs(Integer id) {
        String image = imageMapper.getZczs(id);
        if (image == null)
            return R.info("该用户未上传电子版职称证书", null);
        Map<String, Object> map = new HashMap<>();
        map.put("image", gzipUtils.compress(image));
        return R.ok(map);
    }

    @Override
    public R<Object> insertZczs(Image image) {
        String encoder = "data:image/jpg;base64,";
        String base64 = encoder + ImageUtils.convertImageToBase64Str((String) redisUtils.get(image.getImage()));
        image.setImage(base64);
        imageMapper.insertZczs(image);
        return R.ok("上传成功");
    }

    @Override
    public R<Object> getSfz(Integer id) {
        String image = imageMapper.getSfz(id);
        if (image == null)
            return R.info("该用户未上传电子版身份证", null);
        Map<String, Object> map = new HashMap<>();
        map.put("image", gzipUtils.compress(image));
        return R.ok(map);
    }

    @Override
    public R<Object> insertSfz(Image image) {
        String encoder = "data:image/jpg;base64,";
        String base64 = encoder + ImageUtils.convertImageToBase64Str((String) redisUtils.get(image.getImage()));
        image.setImage(base64);
        imageMapper.insertSfz(image);
        return R.ok("上传成功");
    }

    @Override
    public R<Object> getJsb(Integer id) {
        String image = imageMapper.getJsb(id);
        if (image == null)
            return R.info("该用户未上传电子版驾驶本", null);
        Map<String, Object> map = new HashMap<>();
        map.put("image", gzipUtils.compress(image));
        return R.ok(map);
    }

    @Override
    public R<Object> insertJsb(Image image) {
        String encoder = "data:image/jpg;base64,";
        String base64 = encoder + ImageUtils.convertImageToBase64Str((String) redisUtils.get(image.getImage()));
        image.setImage(base64);
        imageMapper.insertJsb(image);
        return R.ok("上传成功");
    }


    //更新员工年龄，入场时间。。。
    @PostConstruct
    @Scheduled(cron = "0 0 0 * * ?")
    public void checkAllEmployee() {
        List<Employee> list = employeeMapper.getEmployees();
        long stime = System.currentTimeMillis();
        //设置出生日期
        list = list.stream().peek(o -> o.setCsrq(setCsrq(o.getSfz()))).collect(Collectors.toList());
        //设置银行卡类型
        list = list.stream().peek(o -> o.setYhkbz(BankUtil.getNameOfBank(o.getYhkh()))).collect(Collectors.toList());
        //设置性别
        list = list.stream().peek(o -> o.setXb(setXb(o.getSfz()))).collect(Collectors.toList());
        //设置年龄
        list = list.stream().peek(o -> o.setNl(setNl(o.getCsrq()))).collect(Collectors.toList());
        //设置籍贯
        list = list.stream().peek(o -> o.setJg(setJg(o.getSfz()))).collect(Collectors.toList());
        //设置入场年限
        list = list.stream().peek(o -> o.setRcnx(setRcnx(o.getRzrq(), o.getLzrq()))).collect(Collectors.toList());
        //设置合同
        list = list.stream().peek(o -> o.setHt(setHt(o.getHtks(), o.getHtjs()))).collect(Collectors.toList());
        //根据离职日期设置就职状态
        list = list.stream().peek(o -> {
            if (StringUtils.isNotEmpty(o.getLzrq())) o.setJzzt("离职");
        }).collect(Collectors.toList());

        //设置档案号
        list = SetDah(list);
        //未填项
//        list = list.stream().peek(this::SetEmpty).collect(Collectors.toList());
        //入职满三个月，提醒签订合同
        this.SetHtEnoughThreeMonth(list);
        //查询没有档案的人员
        this.CheckEmployeeFiles();
        //查询未办理银行卡人员数目
        this.CheckWrongBankCard(list);

        List<List<Employee>> listList = StringUtils.splitList(list, list.size() / 10).stream().peek(o -> employeeMapper.updateList(o)).collect(Collectors.toList());
        listList.forEach(l -> employeeMapper.updateList(l));
//        employeeMapper.updateList(list);

        long etime = System.currentTimeMillis();
        long time = etime - stime;
        System.out.println("更新完成,耗费时间" + time / 1000.000 + "秒");
    }

    //设置出生日期
    public LocalDateTime setCsrq(String sfz) {
        if ("未填写".equals(sfz) || sfz == null || sfz.isEmpty()) return null;
        int i = 0;
        String year = "";
        if (sfz.length() == 15) {
            year = "19" + sfz.substring(6, 8);
            i = 8;
        }
        if (sfz.length() == 18) {
            year = sfz.substring(6, 10);
            i = 10;
        }
        String month = sfz.substring(i, i + 2);
        String day = sfz.substring(i + 2, i + 4);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String date = year + "-" + month + "-" + day;
        return LocalDate.parse(date, fmt).atTime(LocalTime.now());
    }

    //设置性别
    public String setXb(String sfz) {
        if ("未填写".equals(sfz) || sfz == null || sfz.isEmpty()) return "";
        int number = 0;
        if (sfz.length() == 18) {
            number = sfz.charAt(17 - 1);
        }
        if (sfz.length() == 15) {
            number = sfz.charAt(15 - 1);
        }
        return number % 2 == 0 ? "女" : "男";
    }

    //计算年龄
    public int setNl(LocalDateTime localDateTime) {
        if (localDateTime == null) return 0;
        Calendar cal = Calendar.getInstance();
//        if (cal.before(localDateTime)) {
//            throw new IllegalArgumentException("出生日期大于当前时间");
//        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        //将日期设置为出生日期
        Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        cal.setTime(date);
        //取出出生日期的年、月、日部分
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        int age = yearNow - yearBirth; //计算完整的年份数量
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;//当前日期在生日之前，年龄减一
                }
            } else {
                age--;//当前月份在生日之前，年龄减一
            }
        }
        return age;
    }

    //设置籍贯
    public String setJg(String sfz) {
        if ("未填写".equals(sfz) || sfz == null || sfz.isEmpty()) return "";
        return IdentityCardUtil.getDomicile(sfz);
    }

    //设置入场年限
    public String setRcnx(LocalDateTime localDateTime1, LocalDateTime localDateTime2) {
        if (localDateTime1 == null) return "";
        LocalDate rcrq = localDateTime1.toLocalDate();
        LocalDate today = LocalDate.now();
        if (localDateTime2 != null && localDateTime1.isBefore(localDateTime2)) {
            today = localDateTime2.toLocalDate();
        }
        Period period = Period.between(rcrq, today);
        int days = period.getDays();
        int months = period.getMonths();
        int years = period.getYears();
        String rcnx = days + "天";
        if (months > 0) rcnx = months + "月" + rcnx;
        if (years > 0) rcnx = years + "年" + rcnx;
        return rcnx;
    }

    //设置合同
    public String setHt(LocalDateTime htks, LocalDateTime htjs) {
        if (htks == null)
            return "";
        else {
            if (htjs == null) return "";
            if (htjs.isAfter(LocalDateTime.now()))
                return "已签";
            else return "合同到期";
        }
    }

    //设置档案号
    public List<Employee> SetDah(List<Employee> employeeList) {
        List<Employee> DahIsNull = employeeList.stream().filter(o -> o.getDah() == null).collect(Collectors.toList());
        employeeList = employeeList.stream().filter(o -> o.getDah() != null).sorted(Comparator.comparing(Employee::getDah)).collect(Collectors.toList());
        int firstDah = employeeList.get(0).getDah();
        int lastDah = employeeList.get(employeeList.size() - 1).getDah();

        List<Integer> DahList = new ArrayList<>();
        for (int i = 1; i < employeeList.size() - 1; i++) {
            Integer dah = employeeList.get(i).getDah();
            firstDah++;
            if (dah != firstDah) {
                DahList.add(firstDah);
            }
        }

        for (int i = 0; i < DahIsNull.size() - 1 && i < DahList.size() - 1; i++) {
            Employee employee = DahIsNull.get(i);
            employee.setDah(DahList.get(i));
            employeeList.add(employee);
        }

        DahIsNull = DahIsNull.stream().filter(o -> o.getDah() == null).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(DahIsNull)) {
            for (Employee employee : DahIsNull) {
                employee.setDah(++lastDah);
                employeeList.add(employee);
            }
        }

        return employeeList;
    }

    //将空项设置为"未填写"
    public void SetEmpty(Employee employee) {
        String s = "未填写";
        if (StringUtils.isEmpty(employee.getBm())) employee.setBm(s);
        if (StringUtils.isEmpty(employee.getXb())) employee.setXb(s);
        if (StringUtils.isEmpty(employee.getZw())) employee.setZw(s);
        if (StringUtils.isEmpty(employee.getJzzt())) employee.setJzzt(s);
        if (StringUtils.isEmpty(employee.getByxx())) employee.setByxx(s);
        if (StringUtils.isEmpty(employee.getXl())) employee.setXl(s);
        if (StringUtils.isEmpty(employee.getZy())) employee.setZy(s);
        if (StringUtils.isEmpty(employee.getZcjzj())) employee.setZcjzj(s);
        if (StringUtils.isEmpty(employee.getJg())) employee.setJg(s);
        if (StringUtils.isEmpty(employee.getMz())) employee.setMz(s);
        if (StringUtils.isEmpty(employee.getSfz())) employee.setSfz(s);
        if (StringUtils.isEmpty(employee.getHkszd())) employee.setHkszd(s);
        if (StringUtils.isEmpty(employee.getXzz())) employee.setXzz(s);
        if (StringUtils.isEmpty(employee.getSjh())) employee.setSjh(s);
        if (StringUtils.isEmpty(employee.getYhkh())) employee.setYhkh(s);
        if (StringUtils.isEmpty(employee.getYhkbz())) employee.setYhkbz(s);
        if (StringUtils.isEmpty(employee.getZply())) employee.setZply(s);
        if (StringUtils.isEmpty(employee.getJjlxr())) employee.setJjlxr(s);
        if (StringUtils.isEmpty(employee.getJjlxrdh())) employee.setJjlxrdh(s);
        if (StringUtils.isEmpty(employee.getBmxy())) employee.setBmxy(s);

        if ("无".equals(employee.getBm())) employee.setBm(s);
        if ("无".equals(employee.getXb())) employee.setXb(s);
        if ("无".equals(employee.getZw())) employee.setZw(s);
        if ("无".equals(employee.getJzzt())) employee.setJzzt(s);
        if ("无".equals(employee.getByxx())) employee.setByxx(s);
        if ("无".equals(employee.getXl())) employee.setXl(s);
        if ("无".equals(employee.getZy())) employee.setZy(s);
        if ("无".equals(employee.getZcjzj())) employee.setZcjzj(s);
        if ("无".equals(employee.getJg())) employee.setJg(s);
        if ("无".equals(employee.getMz())) employee.setMz(s);
        if ("无".equals(employee.getSfz())) employee.setSfz(s);
        if ("无".equals(employee.getHkszd())) employee.setHkszd(s);
        if ("无".equals(employee.getXzz())) employee.setXzz(s);
        if ("无".equals(employee.getSjh())) employee.setSjh(s);
        if ("无".equals(employee.getYhkh())) employee.setYhkh(s);
        if ("无".equals(employee.getYhkbz())) employee.setYhkbz(s);
        if ("无".equals(employee.getZply())) employee.setZply(s);
        if ("无".equals(employee.getJjlxr())) employee.setJjlxr(s);
        if ("无".equals(employee.getJjlxrdh())) employee.setJjlxrdh(s);
        if ("无".equals(employee.getBmxy())) employee.setBmxy(s);
    }

    //入场年限满3月，设置系统提醒，签订合同
    @Async
    public void SetHtEnoughThreeMonth(List<Employee> list) {
        List<Employee> employees = list.stream().filter(o -> "在职".equals(o.getJzzt()) && o.getRcnx().startsWith("3月") && !"已签".equals(o.getHt())).collect(Collectors.toList());
        List<Notice> noticeList = employees.stream().map(o -> {
            Notice notice = new Notice();
            notice.setType("实习期已满");
            String message = o.getXm() + o.getXb() + "士，在本公司已经工作" + o.getRcnx() + "，并且还未签订合同！";
            notice.setMessage(message.replace("月0天", "月"));
            notice.setTime(LocalDateTime.now());
            return notice;
        }).collect(Collectors.toList());
        noticeMapper.deleteByTime(LocalDateTime.now());
        noticeMapper.insertList(noticeList);
    }

    //检查在职员工的档案是否遗失
    public void CheckEmployeeFiles() {
        List<Notice> noticeList = employeeMapper.selectListOfNotInfo();
        if (noticeList != null) {
            for (Notice notice : noticeList) {
                notice.setMessage(notice.getMessage() + "，还未录入档案。");
                notice.setType("档案未录入");
                notice.setTime(LocalDateTime.now());
            }
            noticeMapper.insertList(noticeList);
        }
    }

    //查询银行卡不符合类型的人员
    public void CheckWrongBankCard(List<Employee> list) {
        String bankCardType = "招商银行";
        Long count = list.stream().filter(o -> "在职".equals(o.getJzzt())).filter(o -> !o.getYhkbz().contains(bankCardType)).count();

        if (count > 0) {
            List<Notice> noticeList = new ArrayList<>();
            Notice notice = new Notice();
            notice.setMessage("目前有" + count + "人未办理招商银行卡。");
            notice.setType("未办理招商银行卡");
            notice.setTime(LocalDateTime.now());
            noticeList.add(notice);
            noticeMapper.insertList(noticeList);
        }
    }

    //获取所有民族
    public List<String> getMz() {
        String[] strings = {"汉族", "蒙古族", "回族", "藏族", "维吾尔族", "苗族", "彝族", "壮族", "布依族", "朝鲜族", "满族", "侗族", "瑶族", "白族",
                "土家族", "哈尼族", "哈萨克族", "傣族", "黎族", "傈僳族", "佤族", "畲族", "高山族", "拉祜族", "水族", "东乡族", "纳西族", "景颇族", "柯尔克孜族", "土族",
                "达斡尔族", "仫佬族", "羌族", "布朗族", "撒拉族", "毛南族", "仡佬族", "锡伯族", "阿昌族", "普米族", "塔吉克族", "怒族", "乌孜别克族", "俄罗斯族", "鄂温克族",
                "德昂族", "保安族", "裕固族", "京族", "塔塔尔族", "独龙族", "鄂伦春族", "赫哲族", "门巴族", "珞巴族", "基诺族"
        };
        return Arrays.stream(strings).collect(Collectors.toList());
    }
}
